package com.example.buildertest.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.buildertest.mapper.UserMapper;
import com.example.buildertest.model.po.UserPO;
import com.example.buildertest.model.vo.request.UserRequest;
import com.example.buildertest.model.vo.request.UserUpdateRequest;
import com.example.buildertest.model.vo.response.UserRespoonse;
import com.example.buildertest.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * .
 *
 * @author zhuchenglin
 * @since 2024/3/21 14:59
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, UserPO> implements UserService {


    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3, 20, 5,
            TimeUnit.SECONDS, new LinkedBlockingQueue<>(10),
            new ThreadFactory() {
                final ThreadFactory defaultFactory = Executors.defaultThreadFactory();

                @Override
                public Thread newThread(Runnable r) {
                    Thread thread = defaultFactory.newThread(r);
                    thread.setName("HomePageService-" + thread.getName());
                    return thread;
                }
            }, new ThreadPoolExecutor.AbortPolicy());


    @Override
    public UserRespoonse getUser(Long id) {
        List<CompletableFuture<Void>> list = new ArrayList<>(0);
        for (int i = 0; i < 30; i++) {
            // 2、线程池中就3个空闲线程，因为做了 sleep，所以 3个资源都给了父任务
            CompletableFuture<Void> parentTask = CompletableFuture.runAsync(() -> {
                try {
                    System.out.println("父任务执行了：" + Thread.currentThread().getName());
                    TimeUnit.SECONDS.sleep(10);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                    /*// 3、子任务在等待父任务释放资源，父任务在等待子任务执行完，死锁
                    CompletableFuture<Void> childTask = CompletableFuture.runAsync(() -> {
                        System.out.println("子任务执行了：" + Thread.currentThread().getName());
                    }, threadPoolExecutor);
                    childTask.join() ;*/
            }, threadPoolExecutor);
            list.add(parentTask);
        }
        try {
            // 1、开始创建3个异步任务并执行
            CompletableFuture.allOf(list.toArray(new CompletableFuture[0])).get();
//            threadPoolExecutor.shutdown();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        return convertResponse(this.getById(id));
    }

    @Override
    public Boolean saveUser(UserRequest request) {
        return this.save(convert(request));
    }


    @Override
    @Transactional
    public Boolean updateAge(UserUpdateRequest userRequest) {
        UserPO user = this.getById(userRequest.getId());
        if (user != null) {
            user.setAge(user.getAge() + 1);
            this.updateById(user);
        }
        return true;
    }

    private UserRespoonse convertResponse(UserPO userPO) {
        UserRespoonse userRespoonse = new UserRespoonse();
        userRespoonse.setId(userPO.getId());
        userRespoonse.setName(userPO.getName());
        userRespoonse.setAge(userPO.getAge());
        userRespoonse.setSalary(userPO.getSalary());
        userRespoonse.setAlias(userPO.getAlias());
        userRespoonse.setBirthday(userPO.getBirthday());
        userRespoonse.setStartworkdate(userPO.getStartworkdate());
        return userRespoonse;
    }

    private UserPO convert(UserRequest request) {
        UserPO userPO = new UserPO();
        userPO.setName(request.getName());
        userPO.setAge(request.getAge());
        userPO.setSalary(request.getSalary());
        userPO.setAlias(request.getAlias());
        userPO.setBirthday(request.getBirthday());
        userPO.setStartworkdate(request.getStartworkdate());
        return userPO;
    }

    @PreDestroy
    public void myDestroyUserServiceMethod () {
        System.out.println("UserService#myDestroyUserServiceMethod");
    }
}
